//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_FILE_INTERFACE_H
#define _UX_FILE_INTERFACE_H

#include <Includes.h>

namespace Engine
{
namespace FileSystem
{

	//
	// File Interface
	//

	class _EXPORT_ IFile : private CReferenced, public CEngBaseObject
	{
	private:
		virtual void _Release()		{ Release(); }

	public:
		virtual ~IFile() {}

		virtual bool			IsOpen()	const = 0;
		virtual const string &	GetName()	const = 0;
		virtual e_rw_mode::type	GetMode()	const = 0;

		virtual uint Read(void *pBuf, uint uSize) = 0;
		virtual uint Write(const void *pBuf, uint uSize) = 0;
		virtual uint Seek(uint uOffset, e_seek::type eSeekFlag = e_seek::CURRENT) = 0;
		virtual uint GetSize()	const = 0;
		virtual uint GetPos()	const = 0;
		
		virtual uint64 SeekL(uint64 uOffset, e_seek::type eSeekFlag = e_seek::CURRENT) = 0;
		virtual uint64 GetSizeL()	const = 0;
		virtual uint64 GetPosL()	const = 0;

		virtual e_file::type GetFileType()	const = 0;
		

		inline bool IsEOF() const
		{
			return GetPos() >= GetSize();
		}

		inline bool IsEOFL() const
		{
			return GetPosL() >= GetSizeL();
		}

		inline bool ReadS(void *pBuf, uint uSize)
		{
			return Read( pBuf, uSize ) == uSize;
		}

		template <typename T>
		inline bool ReadS(T &tValue)
		{
			return ReadS( &tValue, sizeof(tValue) );
		}

		inline bool WriteS(const void *pBuf, uint uSize)
		{
			return Write( pBuf, uSize ) == uSize;
		}

		template <typename T>
		inline bool WriteS(const T& tValue)
		{
			return WriteS( &tValue, sizeof(tValue) );
		}

		inline bool SeekS(uint uOffset, e_seek::type eSeekFlag = e_seek::CURRENT)
		{
			uint	u_pos = Seek( uOffset, eSeekFlag );

			if ( eSeekFlag == e_seek::SET )
				return ( uOffset == u_pos );
			
			if ( eSeekFlag == e_seek::CURRENT )
				return ( uOffset + GetPos() == u_pos );

			if ( eSeekFlag == e_seek::END )
				return ( GetSize() - uOffset == u_pos );

			return false;
		}

		inline bool SeekSL(uint64 uOffset, e_seek::type eSeekFlag = e_seek::CURRENT)
		{
			uint64	u_pos = SeekL( uOffset, eSeekFlag );

			if ( eSeekFlag == e_seek::SET )
				return ( uOffset == u_pos );
			
			if ( eSeekFlag == e_seek::CURRENT )
				return ( uOffset + GetPosL() == u_pos );

			if ( eSeekFlag == e_seek::END )
				return ( GetSizeL() - uOffset == u_pos );

			return false;
		}
	};

//-------------------------------------------------------------------

}	// FileSystem
}	// Engine

#endif	// _UX_FILE_INTERFACE_H